const babel = require("@babel/core");
const parser = require("@babel/parser");
const traverse = require("@babel/traverse").default;
const t = require("@babel/types");
const fs = require("fs");

class BabelPluginCountdown {
  constructor() {}

  // 定义插件方法
  apply(compiler) {
    console.log("定义插件方法");
    // 监听 compiler 上的 run 事件
    compiler.hooks.run.tapAsync(
      "BabelPluginCountdown",
      (compiler, callback) => {
        // 遍历入口文件并对每个 Vue 组件模板进行编译
        Object.keys(compiler.options.entry).forEach((entryName) => {
          const entryPath = compiler.options.entry[entryName];
          const files = Array.isArray(entryPath) ? entryPath : [entryPath];

          files.forEach((filePath) => {
            // 过滤非 .vue 文件
            if (!/\.vue$/.test(filePath)) {
              return;
            }

            // 读取文件内容
            let source = fs.readFileSync(filePath, "utf-8");

            // 解析 Vue 组件模板为 AST 树
            const ast = parser.parse(source, {
              plugins: ["@babel/plugin-syntax-jsx"],
            });

            // 遍历 AST 树并对组件模板进行转换操作
            traverse(ast, {
              JSXOpeningElement(path) {
                // 判断当前节点是否是 div 元素，并且是否包含 name 属性
                if (
                  path.node.name.name === "div" &&
                  path.node.attributes.find((attr) => attr.name.name === "name")
                ) {
                  // 将 div 元素替换为 countdown 组件
                  path.node.name.name = "countdown";
                  // 移除 name 属性
                  path.node.attributes = path.node.attributes.filter(
                    (attr) => attr.name.name !== "name"
                  );
                  // 添加其他需要的属性、子节点等等
                  path.parentPath.node.children = [
                    t.jsxText(" "),
                    t.jsxElement(
                      t.jsxOpeningElement(t.jsxIdentifier("countdown")),
                      t.jsxClosingElement(t.jsxIdentifier("countdown")),
                      [
                        // 其他子节点
                      ]
                    ),
                    t.jsxText(" "),
                  ];
                }
              },
            });

            // 将 AST 树转换为代码
            const { code } = babel.transformFromAstSync(ast, null, {
              presets: ["@babel/preset-env"],
            });

            // 将编译后的代码写入原文件
            fs.writeFileSync(filePath, code);
          });
        });

        callback(null, compiler);
      }
    );
  }
}

module.exports = BabelPluginCountdown;
